﻿// ----------------------------------------------------------------------
// <author name="Moses Kehengu"/>
// <copyright file="UserManagement.cs" company="Futures Group International">
//     Copyright statement. All right reserved
// </copyright>
//
// ------------------------------------------------------------------------
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
using GenericTools;
using System.Windows.Forms;
using Telerik.WinControls.UI;
using Telerik.WinControls.UI.Export;
using ReportingManagement.Components;
using System.Collections.ObjectModel;
using ReportingManagement.Models;
using System.Drawing;
using DataModels.Enumerations;
using DataModels.Common;

namespace ReportingManagement
{
    public partial class MainWindow
    {
        private bool tabPageUserManagementLoaded = false;
        private bool tabPageUserManagementSMSUserLoaded = false;
        private List<UserInformation> users = null;
        private int adminCount = 0;
        private DataTable SMSUsers = null;

        private ObservableCollection<SMSUserViewModel> smsUsers = new ObservableCollection<SMSUserViewModel>();

        private void tabPageUserManagement_Enter(object sender, EventArgs e)
        {
            try
            {
                if (!tabPageUserManagementLoaded)
                {                   
                    users = new List<UserInformation>();                    
                    PopulateUsersList();
                    //listViewUsers.SetGroupState(ListViewGroupState.Collapsible);

                    if (this.authenticatedUser.Level == AccessLevel.ADMINISTRATOR
                        || this.authenticatedUser.Level == AccessLevel.NATION)
                    {
                        btnAddNewUser.Enabled = true;
                        btnEditUserDetails.Enabled = true;
                        btnDeleteUser.Enabled = true;

                        btnAddSMSUser.Enabled = true;
                        btnEditSMSUser.Enabled = true;
                        btnDeleteSMSUser.Enabled = true;
                    }
                    else
                    {
                        btnAddNewUser.Enabled = false;
                        btnEditUserDetails.Enabled = false;
                        btnDeleteUser.Enabled = false;

                        btnAddSMSUser.Enabled = false;
                        btnEditSMSUser.Enabled = false;
                        btnDeleteSMSUser.Enabled = false;
                    } 
                    
                    if ((AppConfiguration.AccessMethod == DataAccessMethod.OFFLINE_DATA_ACCESS) ||
                         (AppConfiguration.AccessMethod == DataAccessMethod.OFFLINE_DIRECT_ACCESS))
                    {
                        btnAddSMSUser.Enabled = false;
                        btnEditSMSUser.Enabled = false;
                        btnViewHistory.Enabled = false;
                        btnDeleteSMSUser.Enabled = false;
                    }
                    
                    tabPageUserManagementLoaded = true;
                }
            }
            catch (Exception ex)
            {
                DisplayErrorMessage(ex);
            }
        }

        private void tabPageUserManagementSMSUser_Enter(object sender, EventArgs e)
        {
            if (!tabPageUserManagementSMSUserLoaded)
            {
                try
                {
                    PopulateSMSUsersList();
                    tabPageUserManagementSMSUserLoaded = true;
                }
                catch (Exception ex)
                {
                    DisplayErrorMessage(ex);
                }
            }
        }

        private void PopulateUsersList()
        {
            Cursor.Current = Cursors.WaitCursor;
            toolStripStatusLabel.Text = "Loading data, please wait..."; Application.DoEvents();
            DataTable users = null;
            if (this.authenticatedUser.Level == AccessLevel.ADMINISTRATOR) users = Utilities.GetAllUsers();
            else users = Utilities.GetAllUsers(this.authenticatedUser.SupportingPartnerId);
            Cursor.Current = Cursors.Default;
            toolStripStatusLabel.Text = "Ready";

            listViewUsers.Items.Clear();
            this.users.Clear();
            adminCount = 0;
            foreach (DataRow row in users.Rows)
            {
                int id = Int32.Parse(row["ID"].ToString());
                string username = row["Username"].ToString();
                string password = row["Password"].ToString();
                string firstname = row["FirstName"].ToString();
                string lastname = row["LastName"].ToString();
                string emailAddress = row["EmailAddress"].ToString();
                string phoneNumber = row["PhoneNumber"].ToString();
                string accessLevelID = row["AccessLevelID"].ToString();
                string accessLevelValue = row["AccessLevelValue"].ToString();
                int supportingPartnerId = Int32.Parse(row["SupportingPartnerId"].ToString());

                UserInformation user = new UserInformation(id, username, password, firstname, 
                    lastname, emailAddress, phoneNumber, accessLevelID, accessLevelValue, supportingPartnerId);

                string[] data = new string[] 
                    { 
                        user.FullName, 
                        user.EmailAddress, 
                        user.Username, 
                        user.AccessLevelText.ToUpper()
                    };

                ListViewItem item = new ListViewItem(data, -1);
                listViewUsers.Items.Add(item);
                this.users.Add(user);
                if (user.Level == AccessLevel.ADMINISTRATOR) adminCount++;
            }
            lblUsersCount.Text = String.Format("There are {0} registered users", users.Rows.Count);
        }

        private void listViewUsers_SelectedIndexChanged(object sender, EventArgs e)
        {
            try
            {
                int index = listViewUsers.SelectedIndices[0];
                if (this.users[index].Level == AccessLevel.ADMINISTRATOR)
                {
                    if (adminCount == 1) btnDeleteUser.Enabled = false;
                    else
                    {
                        if (this.authenticatedUser.Level == AccessLevel.ADMINISTRATOR
                            || this.authenticatedUser.Level == AccessLevel.NATION)
                        {
                            btnDeleteUser.Enabled = true;
                        }
                        else
                        {
                            btnDeleteUser.Enabled = false;
                        }
                    }
                }
                else
                {
                    if (this.authenticatedUser.Level == AccessLevel.ADMINISTRATOR
                            || this.authenticatedUser.Level == AccessLevel.NATION)
                    {
                        btnDeleteUser.Enabled = true;
                    }
                    else
                    {
                        btnDeleteUser.Enabled = false;
                    }
                }
            }
            catch { }
        }

        private void listViewUsers_DoubleClick(object sender, EventArgs e)
        {
            try
            {
                int index = listViewUsers.SelectedIndices[0];
                UserInformation user = this.users[index];
                // We need atleast one administrator in the system.
                bool onlyAdministrator = ((adminCount == 1) && (user.Level == AccessLevel.ADMINISTRATOR));
                UserDetails userDetails = new UserDetails(user, this.authenticatedUser, onlyAdministrator);
                DialogResult response = userDetails.ShowDialog(this);
                if (response == System.Windows.Forms.DialogResult.OK)
                {
                    Utilities.ClearCache(DataCache.USERS_DETAILS);
                    PopulateUsersList();
                }
            }
            catch (Exception ex)
            {
                DisplayErrorMessage(ex);
            }
        }

        private void btnEditUserDetails_Click(object sender, EventArgs e)
        {
            if (listViewUsers.SelectedIndices.Count == 0)
            {
                MessageBox.Show(this, "Please select a user to edit", AppConfiguration.ApplicationName, 
                    MessageBoxButtons.OK, MessageBoxIcon.Warning);
                return;
            }
            listViewUsers_DoubleClick(null, null);
        }

        private void btnAddNewUser_Click(object sender, EventArgs e)
        {
            if ((AppConfiguration.AccessMethod == DataAccessMethod.OFFLINE_DATA_ACCESS) ||
                (AppConfiguration.AccessMethod == DataAccessMethod.OFFLINE_DIRECT_ACCESS))
            {
                string message = @"The application is running in offline mode. " +
                    "You can not perform any activities that require server " +
                    "connection while you are offline. " +
                    "\n\nYou are current operation will not be processed!";
                MessageBox.Show(this, message, AppConfiguration.ApplicationName,
                    MessageBoxButtons.OK, MessageBoxIcon.Stop);
                return;
            }

            try
            {
                UserDetails userDetails = new UserDetails(this.authenticatedUser);
                DialogResult response = userDetails.ShowDialog(this);
                if (response == System.Windows.Forms.DialogResult.OK)
                {
                    Utilities.ClearCache(DataCache.USERS_DETAILS);
                    PopulateUsersList();
                }
            }
            catch (Exception ex)
            {
                DisplayErrorMessage(ex);
            }
        }

        private void btnDeleteUser_Click(object sender, EventArgs e)
        {
            if ((AppConfiguration.AccessMethod == DataAccessMethod.OFFLINE_DATA_ACCESS) ||
                (AppConfiguration.AccessMethod == DataAccessMethod.OFFLINE_DIRECT_ACCESS))
            {
                string message = @"The application is running in offline mode. " +
                    "You can not perform any activities that require server " +
                    "connection while you are offline. " +
                    "\n\nYou are current operation will not be processed!";
                MessageBox.Show(this, message, AppConfiguration.ApplicationName,
                    MessageBoxButtons.OK, MessageBoxIcon.Stop);
                return;
            }

            if (listViewUsers.SelectedIndices.Count == 0)
            {
                MessageBox.Show(this, "Please select a user to delete", AppConfiguration.ApplicationName,
                    MessageBoxButtons.OK, MessageBoxIcon.Warning);
                return;
            }
            try
            {
                int index = listViewUsers.SelectedIndices[0];
                UserInformation user = this.users[index];
                if (this.authenticatedUser.Level == AccessLevel.NATION)
                {
                    if (user.Level == AccessLevel.ADMINISTRATOR)
                    {
                        string message = @"You are not authorized to perform this operation.";
                        MessageBox.Show(this, message, AppConfiguration.ApplicationName,
                            MessageBoxButtons.OK, MessageBoxIcon.Stop);
                        return;
                    }
                }

                string fullname = user.FullName;
                DialogResult response = MessageBox.Show(this,
                    String.Format("Are you sure you want to delete {0}?", fullname),
                    AppConfiguration.ApplicationName, MessageBoxButtons.YesNo, MessageBoxIcon.Question);
                if (response == System.Windows.Forms.DialogResult.Yes)
                {
                    bool success = user.Delete(this.authenticatedUser.ID);
                    if (success)
                    {
                        MessageBox.Show(this, String.Format("You have successfully deleted {0}", fullname),
                            AppConfiguration.ApplicationName, MessageBoxButtons.OK, MessageBoxIcon.Information);
                        Utilities.ClearCache(DataCache.USERS_DETAILS);
                        PopulateUsersList();
                    }
                    else
                    {
                        MessageBox.Show(this, String.Format("Could not delete {0} from the system!", fullname),
                            AppConfiguration.ApplicationName, MessageBoxButtons.OK, MessageBoxIcon.Error);
                    }
                }
            }
            catch (Exception ex)
            {
                DisplayErrorMessage(ex);
            }
        }

        private void PopulateSMSUsersList()
        {
            Cursor.Current = Cursors.WaitCursor;
            toolStripStatusLabel.Text = "Loading data, please wait..."; Application.DoEvents();
            switch (this.authenticatedUser.Level)
            {
                case AccessLevel.FACILITY:
                    SMSUsers = Utilities.GetAllSMSUsersByFacility(this.authenticatedUser.AccessLevelValue);
                    btnAddSMSUser.Enabled = false;
                    btnEditSMSUser.Enabled = false;
                    btnDeleteSMSUser.Enabled = false;
                    break;

                case AccessLevel.DISTRICT:
                    int districtID = Int32.Parse(this.authenticatedUser.AccessLevelValue);
                    SMSUsers = Utilities.GetAllSMSUsersByDistrict(districtID);
                    btnAddSMSUser.Enabled = false;
                    btnEditSMSUser.Enabled = false;
                    btnDeleteSMSUser.Enabled = false;
                    break;

                case AccessLevel.REGION:
                    int regionId = Int32.Parse(this.authenticatedUser.AccessLevelValue);
                    SMSUsers = Utilities.GetAllSMSUsersByRegion(regionId, this.authenticatedUser.SupportingPartnerId);
                    btnAddSMSUser.Enabled = false;
                    btnEditSMSUser.Enabled = false;
                    btnDeleteSMSUser.Enabled = false;
                    break;

                case AccessLevel.NATION:
                    SMSUsers = Utilities.GetAllSMSUsers(this.authenticatedUser.SupportingPartnerId);
                    //btnAddSMSUser.Enabled = false;
                    //btnEditSMSUser.Enabled = false;
                    //btnDeleteSMSUser.Enabled = false;
                    break;

                case AccessLevel.ADMINISTRATOR:
                    SMSUsers = Utilities.GetAllSMSUsers();
                    break;
            }
 
            Cursor.Current = Cursors.Default;
            toolStripStatusLabel.Text = "Ready";

            /*smsUsers.Clear();
            foreach (DataRow r in SMSUsers.Rows)
            {
                var user = new SMSUserViewModel();
                user.RegionName = r["RegionName"].ToString();
                user.DistrictName = r["District"].ToString();
                user.FacilityName = r["FacName"].ToString();
                user.FacilityCode = r["FacCode"].ToString();
                user.Name = r["Name"].ToString();
                user.PhoneNumber = r["CellNum"].ToString();

                smsUsers.Add(user);
            }
            radGridView2.DataSource = smsUsers;*/

            radGridView2.DataSource = SMSUsers;
            radGridView2.Columns[0].IsVisible = false;  //ApprovedCellNo
            radGridView2.Columns[3].IsVisible = false;  //LangID
            radGridView2.Columns[4].IsVisible = false;  //SendSMS
            radGridView2.Columns[6].IsVisible = false;  //Emails

            //radGridView2.AutoSize = true;
            //radGridView2.AutoSizeColumnsMode = GridViewAutoSizeColumnsMode.Fill;

            lblSMSUsersCount.Text = String.Format("There are {0} registered SMS Users", SMSUsers.Rows.Count);
            if (this.authenticatedUser.Level == AccessLevel.ADMINISTRATOR)
            {
                if (SMSUsers.Rows.Count > 0)
                {
                    btnDeleteSMSUser.Enabled = true;
                    btnEditSMSUser.Enabled = true;
                }
                else
                {
                    btnDeleteSMSUser.Enabled = false;
                    btnEditSMSUser.Enabled = false;
                }               
            }

            // this will take offline mode and respective buttons
            if ((AppConfiguration.AccessMethod == DataAccessMethod.OFFLINE_DATA_ACCESS) ||
                (AppConfiguration.AccessMethod == DataAccessMethod.OFFLINE_DIRECT_ACCESS))
            {
                btnViewReportingHistory.Enabled = false;
                btnDeleteSMSUser.Enabled = false;
                btnEditSMSUser.Enabled = false;
                btnAddSMSUser.Enabled = false;
            }
        }

        private void SelectSMSUser(GridViewRowInfo rowInfo)
        {
            GridViewCellInfo cell = rowInfo.Cells[0];
            int userId = Int32.Parse(cell.Value.ToString());

            try
            {
                Cursor.Current = Cursors.WaitCursor;
                Application.DoEvents();
                SMSUserDetails smsUserDetails = new SMSUserDetails(userId, this.authenticatedUser);
                DialogResult response = smsUserDetails.ShowDialog(this);
                Cursor.Current = Cursors.Default;
                Application.DoEvents();

                if (response == DialogResult.OK)
                {
                    //PopulateSMSUsersList();
                    DataRowView row = rowInfo.DataBoundItem as DataRowView;
                    if (row != null)
                    {
                        if (smsUserDetails.Deleted)
                        {
                            row.Delete();
                        }
                        else
                        {
                            string userPhoneNumber = smsUserDetails.PhoneNumber;
                            DataTable userInfo = Utilities.GetSMSUser(userPhoneNumber);
                            if (userInfo.Rows.Count == 1)
                            {
                                SMSUserViewModel userViewModel = smsUserDetails.SMSUserViewModel;
                                DataRow userInfoRow = userInfo.Rows[0];

                                row["CellNum"] = userInfoRow["CellNum"].ToString();
                                row["Name"] = userInfoRow["Name"].ToString();
                                row["LangID"] = int.Parse(userInfoRow["LangID"].ToString());
                                row["SendSMS"] = bool.Parse(userInfoRow["SendSMS"].ToString());
                                row["FacCode"] = userInfoRow["FacCode"].ToString();
                                row["Email"] = userInfoRow["Email"].ToString();

                                row["FacName"] = userViewModel.FacilityName;
                                row["District"] = userViewModel.DistrictName;
                                row["RegionName"] = userViewModel.RegionName;
                            }
                        }
                        lblSMSUsersCount.Text = String.Format("There are {0} registered SMS Users", radGridView2.RowCount);
                    }
                }
            }
            catch (Exception ex)
            {
                DisplayErrorMessage(ex);
            }
        }

        private void btnAddSMSUser_Click(object sender, EventArgs e)
        {
            SMSUserDetails smsUserDetails = new SMSUserDetails(this.authenticatedUser);
            DialogResult response = smsUserDetails.ShowDialog(this);
            if (response == DialogResult.OK)
            {
                //PopulateSMSUsersList();
                

                string userPhoneNumber = smsUserDetails.PhoneNumber;
                DataTable userInfo = Utilities.GetSMSUser(userPhoneNumber);
                if (userInfo.Rows.Count == 1)
                {
                    SMSUserViewModel userViewModel = smsUserDetails.SMSUserViewModel;
                    DataRow userInfoRow = userInfo.Rows[0];
                    DataRow row = SMSUsers.NewRow();
                    
                    row["ApprovedCellNo"] = int.Parse(userInfoRow["ApprovedCellNo"].ToString());
                    row["CellNum"] = userInfoRow["CellNum"].ToString();
                    row["Name"] = userInfoRow["Name"].ToString();
                    row["LangID"] = int.Parse(userInfoRow["LangID"].ToString());
                    row["SendSMS"] = bool.Parse(userInfoRow["SendSMS"].ToString());
                    row["FacCode"] = userInfoRow["FacCode"].ToString();
                    row["Email"] = userInfoRow["Email"].ToString();
                    
                    row["FacName"] = userViewModel.FacilityName;
                    row["District"] = userViewModel.DistrictName;
                    row["RegionName"] = userViewModel.RegionName;

                    SMSUsers.Rows.Add(row);
                    lblSMSUsersCount.Text = String.Format("There are {0} registered SMS Users", radGridView2.RowCount);
                }                
            }
        }

        private void btnEditSMSUser_Click(object sender, EventArgs e)
        {
            GridViewSelectedRowsCollection rows = radGridView2.SelectedRows;
            if (rows.Count > 0)
            {
                GridViewRowInfo row = rows[0];
                SelectSMSUser(row);
            }
        }

        private void btnDeleteSMSUser_Click(object sender, EventArgs e)
        {
            try
            {
                btnDeleteSMSUser.Enabled = false;
                Application.DoEvents();
                GridViewSelectedRowsCollection selectedRows = radGridView2.SelectedRows;
                if (selectedRows.Count > 0)
                {
                    GridViewRowInfo row = selectedRows[0];
                    GridViewCellInfo cell = row.Cells[0];
                    string id = cell.Value.ToString();
                    int userId = Int32.Parse(id);
                    cell = row.Cells["Name"];
                    string SMSUserName = cell.Value.ToString();

                    DialogResult response = MessageBox.Show(this,
                        String.Format("Are you sure you want to delete SMS user: {0}", SMSUserName),
                        AppConfiguration.ApplicationName, MessageBoxButtons.YesNo, MessageBoxIcon.Question);
                    if (response == System.Windows.Forms.DialogResult.Yes)
                    {
                        bool deleted = Utilities.DeleteSMSUser(userId, this.authenticatedUser.ID);
                        if (deleted)
                        {
                            MessageBox.Show(this, "Operation completed successfully", AppConfiguration.ApplicationName,
                                MessageBoxButtons.OK, MessageBoxIcon.Information);
                            this.DialogResult = System.Windows.Forms.DialogResult.OK;
                            //PopulateSMSUsersList();
                            DataRowView rowView = row.DataBoundItem as DataRowView;
                            if (rowView != null)
                            {
                                rowView.Delete();
                                lblSMSUsersCount.Text = String.Format("There are {0} registered SMS Users", radGridView2.RowCount);
                            }
                        }
                        else throw new Exception("User cannot be deleted at this time. Try again later.");
                    }
                }
            }
            catch (Exception ex)
            {
                DisplayErrorMessage(ex);
            }
            finally
            {
                btnDeleteSMSUser.Enabled = true;
            }
        }

        private void radGridView2_CellDoubleClick(object sender, Telerik.WinControls.UI.GridViewCellEventArgs e)
        {
            GridViewRowInfo row = e.Row;
            SelectSMSUser(row);
        }

        private void btnViewHistory_Click(object sender, EventArgs e)
        {
            GridViewSelectedRowsCollection rows = radGridView2.SelectedRows;
            if (rows.Count > 0)
            {
                GridViewRowInfo row = rows[0];
                try
                {
                    GridViewCellInfo cell = row.Cells[0];
                    string phoneNumber = row.Cells[1].Value.ToString();

                    Cursor.Current = Cursors.WaitCursor;
                    Application.DoEvents();
                    MessageHistory messageHistory = new MessageHistory(phoneNumber);
                    messageHistory.ShowDialog(this);
                    Cursor.Current = Cursors.Default;
                    Application.DoEvents();
                }
                catch (Exception ex)
                {
                    DisplayErrorMessage(ex);
                }
            }
        }

        private void txtSearchSMSUser_TextChanged(object sender, EventArgs e)
        {
            string keyword = txtSearchSMSUser.Text;
            DataTable dataSource = radGridView2.DataSource as DataTable;
            if (dataSource != null)
            {
                if (string.IsNullOrEmpty(keyword))
                {
                    // Reset everything back to the way it was.
                    dataSource.DefaultView.RowFilter = string.Empty;
                    lblSMSUsersCount.Text = String.Format("There are {0} registered users", dataSource.DefaultView.Count);
                    lblSMSUsersCount.ForeColor = Color.Black;
                    return;
                }

                string filterExpression = string.Format(
                    "Name LIKE '%{0}%' " +
                    "OR FacName LIKE '%{0}%' " +
                    "OR CellNum LIKE '%{0}%' " +
                    "OR FacCode LIKE '%{0}%'", keyword);

                dataSource.DefaultView.RowFilter = filterExpression;
                lblSMSUsersCount.Text = String.Format("Search Results: {0} registered users", dataSource.DefaultView.Count);
                lblSMSUsersCount.ForeColor = Color.BlueViolet;
            }
        }
    }
}
